package Top_Interview_Questions_Review._001Tree;

import Top_Interview_Questions_Review._001Tree.Supple.TreeNode;

import java.util.HashMap;

/**
 * @Author: 吕庆龙
 * @Date: 2020/2/8 17:43
 * <p>
 * 官方题解的思想写的不错
 *
 * https://leetcode-cn.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal/solution/xiang-xi-tong-su-de-si-lu-fen-xi-duo-jie-fa-by--22/
 * 我看的是上面那个题解
 */
public class _0105 {
    
    public static void main(String[] args) {
        _0105 test = new _0105();
//        int[] preorder = new int[]{3,9,6,8,20,15,7};
//        int[] inorder = new int[]{6,9,8,3,15,20,7};
        int[] preorder = new int[]{3,9,6,8,20,15,7};
        int[] inorder = new int[]{6,9,8,3,15,20,7};
        TreeNode root = test.buildTree2(preorder, inorder);
        System.out.println(root);
    }



    /*--------------------------------------基于方法一改进---------------------------------------*/

    /**
     *       3
     *     /  \
     *    9    20
     *  /  \  /  \
     * 6   8 15   7
     */
    HashMap<Integer, Integer> map = new HashMap<>();
    public TreeNode buildTree2(int[] preorder, int[] inorder) {

        for (int i = 0; i < inorder.length; i++) {
            map.put(inorder[i], i);
        }
        //[0,preorder.length) 左开右闭，所以后面都是统一的
        return build(preorder, 0, preorder.length-1, inorder, 0, inorder.length-1);
    }


    /*-----------------------------------------------------------------------------------------*/

    TreeNode build(int[] preorder, int preStart, int preEnd,
                   int[] inorder, int inStart, int inEnd) {

        if (preStart > preEnd) {
            return null;
        }

        // root 节点对应的值就是前序遍历数组的第一个元素
        int rootVal = preorder[preStart];
        // rootVal 在中序遍历数组中的索引
        int index = map.get(rootVal);
        int leftSize = index - inStart;

        // 先构造出当前根节点
        TreeNode root = new TreeNode(rootVal);
        // 递归构造左右子树
        root.left = build(preorder, preStart + 1, preStart + leftSize,
                inorder, inStart, index - 1);

        root.right = build(preorder, preStart + leftSize + 1, preEnd,
                inorder, index + 1, inEnd);
        return root;
    }

}
